package com.appium.manager.template;

import com.appium.manager.element.anno.PageElement;
import com.appium.manager.element.anno.interceptor.PageInterceptor;
import com.appium.manager.template.aop.ExSnapshotInterceptor;
import com.appium.manager.template.aop.PageAopHandler;
import com.appium.manager.template.core.AbstractHybridTemplate;
import com.appium.manager.util.FileUtil;
import io.appium.java_client.pagefactory.AppiumFieldDecorator;
import lombok.extern.slf4j.Slf4j;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.ElementLocatorFactory;
import org.openqa.selenium.support.pagefactory.FieldDecorator;

import java.io.File;

import static com.appium.manager.config.AppiumConfig.*;



/**
 * <p>
 *     注解模式
 * </p>
 * @author 大忽悠
 * @create 2022/7/8 14:43
 */
@Slf4j
public class AnnoAppiumHybridTemplate extends AbstractHybridTemplate {

    private PageElement pageElement;
    /**
     * 页面aop代理
     */
    protected PageAopHandler pageAopHandler;


    public AnnoAppiumHybridTemplate() {
        init();
    }

    public AnnoAppiumHybridTemplate(String configPath,String testDataFilePath) {
        this.appiumConfigFilePath=configPath;
        this.testDataFilePath=testDataFilePath;
        init();
    }

    public AnnoAppiumHybridTemplate(String testDataFilePath) {
        this.testDataFilePath=testDataFilePath;
        init();
    }

    public PageElement getPageElement(){
        return pageElement;
    }

    @Override
    protected void afterInit() {
        super.afterInit();
        pageElement=new PageElement(androidDriver,testDataFilePath,this);
        pageAopHandler=new PageAopHandler();
        Boolean openExSnapshot=Boolean.parseBoolean(appiumConfig.getParam(OPEN_EX_SNAPSHOT));
        String snapshotFilePath = appiumConfig.getParam(SNAPSHOT_FILE_PATH);
        pageAopHandler.addInterceptor(new ExSnapshotInterceptor(snapshotFilePath,
                        openExSnapshot,pageElement));
        removeExFile(openExSnapshot,Boolean.parseBoolean(appiumConfig.getParam(REMOVE_BEFORE_START)),snapshotFilePath);
    }

    /**
     * 移除上一次生成的异常截图文件
     */
    private void removeExFile(Boolean openExSnapshot, Boolean removeBeforeStart,String snapshotFilePath) {
        if(openExSnapshot){
            log.info("开启了异常截图");
        }
        if(openExSnapshot&&removeBeforeStart){
            log.info("在启动前将会删除上一次生成的异常截图文件");
            FileUtil.removeFile(snapshotFilePath);
        }
    }

    /**
     * 对页面进行代码
     */
    public <T> T initPage(T page){
       return pageAopHandler.createProxy(page);
    }


    //--------------------------------拦截器----------------------------------------------------

    public AnnoAppiumHybridTemplate addInterceptor(PageInterceptor pageInterceptor, String... methodNames) {
        pageElement.addInterceptor(pageInterceptor, methodNames);
        return this;
    }

    public void invoke(String curTestMethodName) throws InterruptedException {
        pageElement.invoke(curTestMethodName);
    }

    //-------------------------PageFactory提供的方法-------------------------------------------------

    /**
     * 如果当前对象内部用注解标注了属性来获取对应的元素
     */
    public void initAnnoFiledElements(Object page){initElements(new AppiumFieldDecorator(androidDriver), page);}

    public <T> T initElements(Class<T> pageClassToProxy) {
        return PageFactory.initElements(androidDriver,pageClassToProxy);
    }

    public void initElements(Object page) {
        PageFactory.initElements(androidDriver,page);
    }

    public  void initElements(ElementLocatorFactory factory, Object page) {
        PageFactory.initElements(factory,page);
    }

    public void initElements(FieldDecorator decorator, Object page) {
        PageFactory.initElements(decorator,page);
    }
}
